Xv6 Lab: lazy page allocation 您所在的位置:网站首页 mit 6s081lab5 xv6 lazy page allocation Xv6 Lab: lazy page allocation

Xv6 Lab: lazy page allocation

2023-04-08 16:07| 来源: 网络整理| 查看: 265

「这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战」

Meaning Unknown's Head Image

Lab: xv6 lazy page allocation

pdos.csail.mit.edu/6.S081/2020…

新的 2020 版哦。

$ git fetch $ git checkout lazy $ make clean 复制代码 Eliminate allocation from sbrk()

这道题就是把 sys_sbrk 里的 growproc 调用删了,等用到的时候再去分配内存。如果是空间减小,要取消分配。

uint64 sys_sbrk(void) { int addr; int n; struct proc *p = myproc(); //(+) if(argint(0, &n) < 0) return -1; addr = p->sz; // old sz p->sz += n; if (n < 0) { // 空间减小: 取消分配 uvmdealloc(p->pagetable, addr, p->sz); } return addr; } 复制代码 Lazy allocation

在 vm.c 里面实现惰性分配(莫忘在 defs.h 中声明函数):

#include "spinlock.h" //(+) #include "proc.h" //(+) // lazy allocation memory va for proc p: handle page-fault. // return allocated memory (pa), 0 for failed uint64 lazyalloc(struct proc * p, uint64 va){ if(va >= p->sz || va < PGROUNDUP(p->trapframe->sp)){ return 0; } char * mem; uint64 a = PGROUNDDOWN(va); mem = kalloc(); if(mem == 0){ return 0; } memset(mem, 0, PGSIZE); if(mappages(p->pagetable, a, PGSIZE, (uint64)mem, PTE_W|PTE_X|PTE_R|PTE_U) != 0){ kfree(mem); return 0; } return (uint64)mem; } 复制代码

在 usertrap (trap.c) 里处理缺页错误,尝试惰性分配(掉上面写的那个函数,失败就杀掉进程):

void usertrap(void) { ... if(r_scause() == 8){ // system call ... } else if((which_dev = devintr()) != 0){ // ok } else if((r_scause() == 13) || (r_scause() == 15)){ // page fault: (+) if (lazyalloc(myproc(), r_stval()) killed = 1; } } else { ... } ... } 复制代码

最后改一点点细节,把各种缺页会爆出的 panic 干掉(vm.c里)。以前这些情况正常是不会发生的,但现在惰性分配会带来缺页,所以要告诉操作系统遇到这些事情时 don't panic,继续往下跑就行了:

(这里的代码我懒得改结构就上goto了,但你应该去改if结构,而不是goto)

// vm.c ... //(+) uint64 walkaddr(pagetable_t pagetable, uint64 va) { ... if(pte == 0) goto lzac; if((*pte & PTE_V) == 0) goto lzac; if((*pte & PTE_U) == 0) goto lzac; pa = PTE2PA(*pte); if (0) { lzac: if ((pa = lazyalloc(myproc(), va)) sz; - if(growproc(n) < 0) - return -1; + addr = p->sz; // old sz + p->sz += n; + if (n < 0) { + uvmdealloc(p->pagetable, addr, p->sz); + } return addr; } diff --git a/kernel/trap.c b/kernel/trap.c index a63249e..fc08231 100644 --- a/kernel/trap.c +++ b/kernel/trap.c @@ -67,6 +67,11 @@ usertrap(void) syscall(); } else if((which_dev = devintr()) != 0){ // ok + } else if((r_scause() == 13) || (r_scause() == 15)){ // page fault + // lazy allocation + if (lazyalloc(myproc(), r_stval()) killed = 1; + } } else { printf("usertrap(): unexpected scause %p pid=%d\n", r_scause(), p->pid); printf(" sepc=%p stval=%p\n", r_sepc(), r_stval()); diff --git a/kernel/vm.c b/kernel/vm.c index bccb405..f3235c3 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -5,6 +5,8 @@ #include "riscv.h" #include "defs.h" #include "fs.h" +#include "spinlock.h" +#include "proc.h" /* * the kernel's page table. @@ -102,12 +104,19 @@ walkaddr(pagetable_t pagetable, uint64 va) pte = walk(pagetable, va, 0); if(pte == 0) - return 0; + goto lzac; if((*pte & PTE_V) == 0) - return 0; + goto lzac; if((*pte & PTE_U) == 0) - return 0; + goto lzac; pa = PTE2PA(*pte); + + if (0) { +lzac: + if ((pa = lazyalloc(myproc(), va)) pid); \ + printf(" sepc=%p stval=%p\n", r_sepc(), r_stval()); \ +} + if(va >= p->sz || va < PGROUNDUP(p->trapframe->sp)){ + #if lazyalloc_debug + lazyalloc_warn("vm addr higher then any allocated with sbrk\n"); + #endif + return 0; + } + char * mem; + uint64 a = PGROUNDDOWN(va); + mem = kalloc(); + if(mem == 0){ + #if lazyalloc_debug + lazyalloc_warn("kalloc() == 0\n"); + #endif + return 0; + } + memset(mem, 0, PGSIZE); + if(mappages(p->pagetable, a, PGSIZE, (uint64)mem, PTE_W|PTE_X|PTE_R|PTE_U) != 0){ + #if lazyalloc_debug + lazyalloc_warn("mappages() != 0\n"); + #endif + kfree(mem); + return 0; + } + + return (uint64)mem; +} 复制代码 结果

最后 make grade 看成绩了:

xv6-labs-2020 $ make grade ... == Test running lazytests == $ make qemu-gdb (7.7s) == Test lazy: map == lazy: map: OK == Test lazy: unmap == lazy: unmap: OK == Test usertests == $ make qemu-gdb (145.8s) == Test usertests: pgbug == usertests: pgbug: OK == Test usertests: sbrkbugs == usertests: sbrkbugs: OK == Test usertests: argptest == usertests: argptest: OK == Test usertests: sbrkmuch == ... OK ... == Test usertests: dirfile == usertests: dirfile: OK == Test usertests: iref == usertests: iref: OK == Test usertests: forktest == usertests: forktest: OK == Test time == time: OK Score: 119/119 复制代码

CDFMLR

顶部图片来自于网络,系随机选取的图片,仅用于检测屏幕显示的机械、光电性能,与文章的任何内容及观点无关,也并不代表本人局部或全部同意、支持或者反对其中的任何内容及观点。如有侵权,联系删除。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有